import type { App } from 'vue';
import { message, Modal } from 'ant-design-vue';

/**
 * 基础异常类
 */
export class BaseError extends Error {
    code?: number;
    details?: any;

    constructor(message: string, code?: number, details?: any) {
        super(message);
        this.name = 'BaseError';
        this.code = code;
        this.details = details;//错误详情（可选）
    }
}

/**
 * 网络异常
 */
export class NetworkError extends BaseError {
    constructor(message: string = '网络请求失败', code?: number, details?: any) {
        super(message, code, details);
        this.name = 'NetworkError';
    }
}

/**
 * 业务异常
 */
export class BusinessError extends BaseError {
    constructor(message: string = '业务处理失败', code?: number, details?: any) {
        super(message, code, details);
        this.name = 'BusinessError';
    }
}

/**
 * 表单验证异常
 */
export class ValidationError extends BaseError {
    constructor(message: string = '表单验证失败', details?: Record<string, string[]>) {
        /**
         * 400 错误码表示请求数据格式错误
         */
        super(message, 400, details);
        this.name = 'ValidationError';
    }
}

/**
 * 全局异常处理器初始化,在 main.ts 处注册
 */
export function setupErrorHandler(app: App) {
    // Vue 组件错误捕获
    app.config.errorHandler = (err, instance, info) => {
        console.error('Vue 组件错误:', err, instance, info);
        handleError(err);
    };

    // 未处理的 Promise 错误
    window.addEventListener('unhandledrejection', (event) => {
        console.error('未处理的 Promise 错误:', event.reason);
        handleError(event.reason);
        event.preventDefault();
    });

    // 同步代码错误
    window.addEventListener('error', (event) => {
        if (event.error !== null) {
            console.error('全局同步错误:', event.error);
            handleError(event.error);
        } else { //error 为空时,不捕获异常，不处理。

        }
    });
}

/**
 * 核心错误处理逻辑
 */
export function handleError(err: any) {
    if (err instanceof BaseError) {
        handleCustomError(err);
    } else {
        handleNativeError(err);
    }
}

/**
 * 处理自定义异常
 */
function handleCustomError(err: BaseError) {
    switch (err.name) {
        case 'NetworkError':
            message.error(err.message);
            break;
        case 'BusinessError':
            if (err.code === 30007) {
                Modal.error({
                    title: '登录过期',
                    content: err.message,
                    onOk: () => (window.location.href = '/login')
                });
            } else {
                message.error(err.message);
            }
            break;
        case 'ValidationError':
            const firstError = Object.values(err.details as Record<string, string[]>)[0]?.[0] || err.message;
            message.warning(firstError);
            break;
        default:
            message.error(err.message);
    }
}

/**
 * 处理原生异常
 */
function handleNativeError(err: Error) {
    if (err.message.includes('Network Error')) {
        message.error('网络连接失败');
    } else if (err.message.includes('timeout')) {
        message.error('请求超时');
  } else {
        if (import.meta.env.DEV) {
            Modal.error({ title: '错误', content: err.stack });
        } else {
            message.error('系统错误，请联系管理员');
            reportErrorToServer(err);
        }
    }
}

/**
 * 错误上报
 */
function reportErrorToServer(err: Error) {
    // 收集错误信息
    const errorData = {
        message: err.message,
        stack: err.stack,
        url: window.location.href,
        time: new Date().toISOString(),
        env: import.meta.env.MODE // 环境标识（开发/生产）
    };
    // 发送到后端监控接口
    fetch('/api/monitor/error', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify(errorData),
        keepalive: true // 确保页面关闭时也能上报
    }).catch(() => {}); // 上报失败不处理
}